//
//  ThreadViewController.swift
//  swift各类控件集锦
//
//  Created by iosdev1 on 2017/1/6.
//  Copyright © 2017年 zyy. All rights reserved.
//

import UIKit

class ThreadViewController: ZyBaseViewController {

    var thread:Thread! = nil;
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
//        这套方案是经过苹果封装后的，并且完全面向对象的。所以你可以直接操控线程对象，非常直观和方便。但是，它的生命周期还是需要我们手动管理，所以这套方案也是偶尔用用，比如 [NSThread currentThread]，它可以获取当前线程类，你就可以知道当前线程的各种属性，用于调试十分方便。下面来看看它的一些用法。
//        self.threadFunc()


////        GCD
//        Grand Central Dispatch，听名字就霸气。它是苹果为多核的并行运算提出的解决方案，所以会自动合理地利用更多的CPU内核（比如双核、四核），最重要的是它会自动管理线程的生命周期（创建线程、调度任务、销毁线程），完全不需要我们管理，我们只需要告诉干什么就行。同时它使用的也是 c语言，不过由于使用了 Block（Swift里叫做闭包），使得使用起来更加方便，而且灵活
        self.gcdFunc();
    }

    
// MARK:   Thread
    func threadFunc() -> Void {
//        NSThread 用起来也挺简单的，因为它就那几种方法。同时，我们也只有在一些非常简单的场景才会用 NSThread, 毕竟它还不够智能，不能优雅地处理多线程中的其他高级概念
//        1先创建线程类，再启动
        //创建
        thread = Thread.init(target: self, selector: #selector(threadFuncStart(data:)), object: ["thread":"zyy"])
        
        //启动
        thread?.start()
        
//        2创建并自动启动,下面一句等同于上面两句
//        Thread.detachNewThreadSelector(#selector(threadFuncStart(data:)), toTarget: self, with: ["thread":"zyy"])

    }
    
    func threadFuncStart(data:Any) -> Void {
        print("线程Thread:\(data)\n 属性:\(thread.isExecuting)，\n 是否结束:\(thread.isFinished)")
        print("名字：\(String(describing: thread.name))")
        thread.name = "不知道是不是主线程"
        print("修改之后的名字：\(String(describing: thread.name))")

        print("获取当前线程信息:\(Thread.current)");
        print("获取当前主线程信息:\(Thread.main)");
        print("获取线程thread信息:\(thread)")

        if thread.isMainThread {
            print("thread就是主线程")
        }else{
            print("thread不是主线程")
        }

        if Thread.current == Thread.main {
            print("当前就是主线程")
        }else{
            print("当前不是主线程")
        }
        thread = Thread.main;
        print("获取线程thread信息:\(thread),变为主线程")
        //使当前线程暂停一段时间，或者暂停到某个时刻
//        Thread.sleep(until: Date.init())
//        Thread.sleep(forTimeInterval: TimeInterval.init())

        if thread.isCancelled {
            print("线程已取消");
        }else{
            //取消线程
            thread.cancel()
        }
    }

    
// MARK:   GCD
    func gcdFunc() -> Void {
//        在 GCD 中，加入了两个非常重要的概念： 任务 和 队列。
//        任务：即操作，你想要干什么，说白了就是一段代码，在 GCD 中就是一个 Block，所以添加任务十分方便。任务有两种执行方式： 同步执行 和 异步执行，他们之间的区别是 是否会创建新的线程。

        //        同步（sync） 和 异步（async） 的主要区别在于会不会阻塞当前线程，直到 Block 中的任务执行完毕！
//        如果是 同步（sync） 操作，它会阻塞当前线程并等待 Block 中的任务执行完毕，然后当前线程才会继续往下运行。
//        如果是 异步（async）操作，当前线程会直接往下执行，它不会阻塞当前线程。

//        队列：用于存放任务。一共有两种队列， 串行队列 和 并行队列

        //        串行队列 中的任务会根据队列的定义 FIFO 的执行，一个接一个的先进先出的进行执行。放到串行队列的任务，GCD 会 FIFO（先进先出） 地取出来一个，执行一个，然后取下一个，这样一个一个的执行

//        放到并行队列的任务，GCD 也会 FIFO的取出来，但不同的是，它取出来一个就会放到别的线程，然后再取出来一个又放到另一个的线程。这样由于取的动作很快，忽略不计，看起来，所有的任务都是一起执行的。不过需要注意，GCD 会根据系统资源控制并行的数量，所以如果任务很多，它并不会让所有任务同时执行。


//        主队列：这是一个特殊的 串行队列。什么是主队列，大家都知道吧，它用于刷新 UI，任何需要刷新 UI 的工作都要在主队列执行，所以一般耗时的任务都要放到别的线程执行。
        let queue:DispatchQueue = DispatchQueue.main;
        print("主队列：\(queue)")

        



    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}
